home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / src / impurity / tracepath.c < prev   
C/C++ Source or Header  |  2006-06-30  |  8KB  |  383 lines

  1. /*
  2.  * tracepath.c
  3.  *
  4.  *        This program is free software; you can redistribute it and/or
  5.  *        modify it under the terms of the GNU General Public License
  6.  *        as published by the Free Software Foundation; either version
  7.  *        2 of the License, or (at your option) any later version.
  8.  *
  9.  * Authors:    Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  10.  */
  11. #include <asm/types.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <unistd.h>
  15. #include <sys/socket.h>
  16. #include <linux/errqueue.h>
  17. #include <errno.h>
  18. #include <string.h>
  19. #include <netdb.h>
  20. #include <netinet/in.h>
  21. #include <resolv.h>
  22. #include <sys/time.h>
  23. #include <sys/uio.h>
  24. #include <arpa/inet.h>
  25. #include <signal.h>
  26. struct hhistory
  27. {
  28.     int    hops;
  29.     struct timeval sendtime;
  30. };
  31.  
  32. struct hhistory his[64];
  33. int hisptr;
  34.  
  35. struct sockaddr_in target;
  36. __u16 base_port;
  37.  
  38. const int overhead = 28;
  39. int mtu = 65535;
  40. int hops_to = -1;
  41. int hops_from = -1;
  42. int no_resolve = 0;
  43.  
  44. struct probehdr
  45. {
  46.     __u32 ttl;
  47.     struct timeval tv;
  48. };
  49.  
  50. void data_wait(int fd)
  51. {
  52.     fd_set fds;
  53.     struct timeval tv;
  54.     FD_ZERO(&fds);
  55.     FD_SET(fd, &fds);
  56.     tv.tv_sec = 1;
  57.     tv.tv_usec = 0;
  58.     select(fd+1, &fds, NULL, NULL, &tv);
  59. }
  60.  
  61. int recverr(int fd, int ttl)
  62. {
  63.     int res;
  64.     struct probehdr rcvbuf;
  65.     char cbuf[512];
  66.     struct iovec  iov;
  67.     struct msghdr msg;
  68.     struct cmsghdr *cmsg;
  69.     struct sock_extended_err *e;
  70.     struct sockaddr_in addr;
  71.     struct timeval tv;
  72.     struct timeval *rettv;
  73.     int slot;
  74.     int rethops;
  75.     int sndhops;
  76.     int progress = -1;
  77.     int broken_router;
  78.     
  79. restart:
  80.     memset(&rcvbuf, -1, sizeof(rcvbuf));
  81.     iov.iov_base = &rcvbuf;
  82.     iov.iov_len = sizeof(rcvbuf);
  83.     msg.msg_name = (__u8*)&addr;
  84.     msg.msg_namelen = sizeof(addr);
  85.     msg.msg_iov = &iov;
  86.     msg.msg_iovlen = 1;
  87.     msg.msg_flags = 0;
  88.     msg.msg_control = cbuf;
  89.     msg.msg_controllen = sizeof(cbuf);
  90.  
  91.     gettimeofday(&tv, NULL);
  92.     res = recvmsg(fd, &msg, MSG_ERRQUEUE);
  93.     if (res < 0) {
  94.         if (errno == EAGAIN)
  95.             return progress;
  96.         goto restart;
  97.     }
  98.  
  99.     progress = mtu;
  100.  
  101.     rethops = -1;
  102.     sndhops = -1;
  103.     e = NULL;
  104.     rettv = NULL;
  105.     slot = ntohs(addr.sin_port) - base_port;
  106.     if (slot>=0 && slot < 63 && his[slot].hops) {
  107.         sndhops = his[slot].hops;
  108.         rettv = &his[slot].sendtime;
  109.         his[slot].hops = 0;
  110.     }
  111.     broken_router = 0;
  112.     if (res == sizeof(rcvbuf)) {
  113.         if (rcvbuf.ttl == 0 || rcvbuf.tv.tv_sec == 0) {
  114.             broken_router = 1;
  115.         } else {
  116.             sndhops = rcvbuf.ttl;
  117.             rettv = &rcvbuf.tv;
  118.         }
  119.     }
  120.  
  121.     for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
  122.         if (cmsg->cmsg_level == SOL_IP) {
  123.             if (cmsg->cmsg_type == IP_RECVERR) {
  124.                 e = (struct sock_extended_err *) CMSG_DATA(cmsg);
  125.             } else if (cmsg->cmsg_type == IP_TTL) {
  126.                 rethops = *(int*)CMSG_DATA(cmsg);
  127.             } else { 
  128.                 printf("cmsg:%d\n ", cmsg->cmsg_type); 
  129.             }
  130.         }
  131.     }
  132.     if (e == NULL) {
  133.         printf("no info\n");
  134.         return 0;
  135.     }
  136.     if (e->ee_origin == SO_EE_ORIGIN_LOCAL) {
  137.         printf("%2d?: %-15s ", ttl, "[LOCALHOST]");
  138.     } else if (e->ee_origin == SO_EE_ORIGIN_ICMP) {
  139.         char abuf[128];
  140.         struct sockaddr_in *sin = (struct sockaddr_in*)(e+1);
  141.  
  142.         inet_ntop(AF_INET, &sin->sin_addr, abuf, sizeof(abuf));
  143.  
  144.         if (sndhops>0)
  145.             printf("%2d:  ", sndhops);
  146.         else
  147.             printf("%2d?: ", ttl);
  148.  
  149.         if(!no_resolve) {
  150.             char fabuf[256];
  151.             struct hostent *h;
  152.             fflush(stdout);
  153.             h = gethostbyaddr((char *) &sin->sin_addr, sizeof(sin->sin_addr), AF_INET);
  154.             snprintf(fabuf, sizeof(fabuf), "%s (%s)", h ? h->h_name : abuf, abuf);
  155.             printf("%-52s ", fabuf);
  156.         } else {
  157.             printf("%-15s ", abuf);
  158.         }
  159.     }
  160.  
  161.     if (rethops>=0) {
  162.         if (rethops<=64)
  163.             rethops = 65-rethops;
  164.         else if (rethops<=128)
  165.             rethops = 129-rethops;
  166.         else
  167.             rethops = 256-rethops;
  168.         if (sndhops>=0 && rethops != sndhops)
  169.             printf("asymm %2d ", rethops);
  170.         else if (sndhops<0 && rethops != ttl)
  171.             printf("asymm %2d ", rethops);
  172.     }
  173.  
  174.     if (rettv) {
  175.         int diff = (tv.tv_sec-rettv->tv_sec)*1000000+(tv.tv_usec-rettv->tv_usec);
  176.         printf("%3d.%03dms ", diff/1000, diff%1000);
  177.         if (broken_router)
  178.             printf("(This broken router returned corrupted payload) ");
  179.     }
  180.  
  181.     switch (e->ee_errno) {
  182.     case ETIMEDOUT:
  183.         printf("\n");
  184.         break;
  185.     case EMSGSIZE:
  186.         printf("pmtu %d\n", e->ee_info);
  187.         mtu = e->ee_info;
  188.         progress = mtu;
  189.         break;
  190.     case ECONNREFUSED:
  191.         printf("reached\n");
  192.         hops_to = sndhops<0 ? ttl : sndhops;
  193.         hops_from = rethops;
  194.         return 0;
  195.     case EPROTO:
  196.         printf("!P\n");
  197.         return 0;
  198.     case EHOSTUNREACH:
  199.         if (e->ee_origin == SO_EE_ORIGIN_ICMP &&
  200.             e->ee_type == 11 &&
  201.             e->ee_code == 0) {
  202.             printf("\n");
  203.             break;
  204.         }
  205.         printf("!H\n");
  206.         return 0;
  207.     case ENETUNREACH:
  208.         printf("!N\n");
  209.         return 0;
  210.     case EACCES:
  211.         printf("!A\n");
  212.         return 0;
  213.     default:
  214.         printf("\n");
  215.         errno = e->ee_errno;
  216.         perror("NET ERROR");
  217.         return 0;
  218.     }
  219.     goto restart;
  220. }
  221.  
  222. int probe_ttl(int fd, int ttl)
  223. {
  224.     int i;
  225.     char sndbuf[mtu];
  226.     struct probehdr *hdr = (struct probehdr*)sndbuf;
  227.  
  228.     memset(sndbuf,0,mtu);
  229.  
  230. restart:
  231.     for (i=0; i<10; i++) {
  232.         int res;
  233.  
  234.         hdr->ttl = ttl;
  235.         target.sin_port = htons(base_port + hisptr);
  236.         gettimeofday(&hdr->tv, NULL);
  237.         his[hisptr].hops = ttl;
  238.         his[hisptr].sendtime = hdr->tv;
  239.         if (sendto(fd, sndbuf, mtu-overhead, 0, (struct sockaddr*)&target, sizeof(target)) > 0)
  240.             break;
  241.         res = recverr(fd, ttl);
  242.         his[hisptr].hops = 0;
  243.         if (res==0)
  244.             return 0;
  245.         if (res > 0)
  246.             goto restart;
  247.     }
  248.     hisptr = (hisptr + 1)&63;
  249.  
  250.     if (i<10) {
  251.         data_wait(fd);
  252.         if (recv(fd, sndbuf, sizeof(sndbuf), MSG_DONTWAIT) > 0) {
  253.             printf("%2d?: reply received 8)\n", ttl);
  254.             return 0;
  255.         }
  256.         return recverr(fd, ttl);
  257.     }
  258.  
  259.     printf("%2d:  send failed\n", ttl);
  260.     return 0;
  261. }
  262.  
  263. static void usage(void) __attribute((noreturn));
  264.  
  265. static void usage(void)
  266. {
  267.     fprintf(stderr, "Usage: tracepath [-n] <destination>[/<port>]\n");
  268.     exit(-1);
  269. }
  270.  
  271. int
  272. oldmain(int argc, char **argv)
  273. {
  274.     struct hostent *he;
  275.     int fd;
  276.     int on;
  277.     int ttl;
  278.     char *p;
  279.     int ch;
  280.  
  281.     while ((ch = getopt(argc, argv, "nh?")) != EOF) {
  282.         switch(ch) {
  283.         case 'n':    
  284.             no_resolve = 1;
  285.             break;
  286.         default: ;    
  287.         }
  288.     }
  289.  
  290.     argc -= optind;
  291.     argv += optind;
  292.  
  293.     if (argc != 1)
  294.         usage();
  295.  
  296.  
  297.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  298.     if (fd < 0) {
  299.         perror("socket");
  300.         exit(1);
  301.     }
  302.     target.sin_family = AF_INET;
  303.  
  304.     p = strchr(argv[0], '/');
  305.     if (p) {
  306.         *p = 0;
  307.         base_port = atoi(p+1);
  308.     } else
  309.         base_port = 44444;
  310.     he = gethostbyname(argv[0]);
  311.     if (he == NULL) {
  312.         herror("gethostbyname");
  313.         exit(1);
  314.     }
  315.     memcpy(&target.sin_addr, he->h_addr, 4);
  316.  
  317.     on = IP_PMTUDISC_DO;
  318.     if (setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &on, sizeof(on))) {
  319.         perror("IP_MTU_DISCOVER");
  320.         exit(1);
  321.     }
  322.     on = 1;
  323.     if (setsockopt(fd, SOL_IP, IP_RECVERR, &on, sizeof(on))) {
  324.         perror("IP_RECVERR");
  325.         exit(1);
  326.     }
  327.     if (setsockopt(fd, SOL_IP, IP_RECVTTL, &on, sizeof(on))) {
  328.         perror("IP_RECVTTL");
  329.         exit(1);
  330.     }
  331.  
  332.     for (ttl=1; ttl<32; ttl++) {
  333.         int res;
  334.         int i;
  335.  
  336.         on = ttl;
  337.         if (setsockopt(fd, SOL_IP, IP_TTL, &on, sizeof(on))) {
  338.             perror("IP_TTL");
  339.             exit(1);
  340.         }
  341.  
  342.         for (i=0; i<3; i++) {
  343.             res = probe_ttl(fd, ttl);
  344.             if (res == 0)
  345.                 goto done;
  346.             if (res > 0)
  347.                 break;
  348.         }
  349.  
  350.         if (res < 0)
  351.             printf("%2d:  no reply\n", ttl);
  352.     }
  353.     printf("     Too many hops: pmtu %d\n", mtu);
  354. done:
  355.     printf("     Resume: pmtu %d ", mtu);
  356.     if (hops_to>=0)
  357.         printf("hops %d ", hops_to);
  358.     if (hops_from>=0)
  359.         printf("back %d ", hops_from);
  360.     printf("\n");
  361.     exit(0);
  362. }
  363. extern char** environ;
  364. int main()
  365. {
  366.     char *args[4];
  367.     char ipaddr[256];
  368.     char *myenv[1]={0};
  369. /* Point environment to a sane place */
  370.     environ=myenv;
  371.     signal(SIGPIPE, SIG_DFL);
  372.     printf("Second stage OK. Which ipaddr should I try ?\n");
  373.     scanf("%s", ipaddr);
  374.  
  375. /* Prepare command line */
  376.     args[0]="tracepath";
  377.     args[1]="-n";
  378.     args[2]=ipaddr;
  379.     args[3]=0;
  380. /* Call original main() */
  381.     oldmain(3, args);
  382. }
  383.